package com.youlai.boot.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.likavn.eventbus.core.api.MsgSender;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.core.security.model.SysUserDetails;
import com.youlai.boot.core.security.util.SecurityUtils;
import com.youlai.boot.excel.ExcelFillMergeHandler;
import com.youlai.boot.system.converter.LpsOrderConverter;
import com.youlai.boot.system.enums.ExcelTemplateEnum;
import com.youlai.boot.system.enums.LpsOrderTypeEnum;
import com.youlai.boot.system.enums.OrderTypeEnum;
import com.youlai.boot.system.mapper.*;
import com.youlai.boot.system.model.entity.*;
import com.youlai.boot.system.model.excel.*;
import com.youlai.boot.system.model.form.LpsOrderForm;
import com.youlai.boot.system.model.query.LpsOrderQuery;
import com.youlai.boot.system.model.vo.*;
import com.youlai.boot.system.service.*;
import com.youlai.boot.system.service.order.*;
import com.youlai.boot.util.ExcelUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 莱普森订单服务实现类
 *
 * @author lwb
 * @since 2025-07-13 16:00
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class LpsOrderServiceImpl extends ServiceImpl<LpsOrderMapper, LpsOrder> implements LpsOrderService {

    private final LpsOrderConverter lpsOrderConverter;

    @Resource
    private LpsOrderCdjgMapper lpsOrderCdjgMapper;
    @Resource
    private LpsOrderCdjgService lpsOrderCdjgService;
    @Resource
    private LpsOrderCdjgCMapper lpsOrderCdjgCMapper;
    @Resource
    private LpsOrderCdjgCService lpsOrderCdjgCService;
    @Resource
    private LpsOrderPjMapper lpsOrderPjMapper;
    @Resource
    private LpsOrderPjService lpsOrderPjService;
    @Resource
    private LpsOrderXcpMapper lpsOrderXcpMapper;
    @Resource
    private LpsOrderXcpService lpsOrderXcpService;
    @Resource
    private LpsOrderXianMapper lpsOrderXianMapper;
    @Resource
    private LpsOrderXianService lpsOrderXianService;
    @Resource
    private LpsWlService lpsWlService;
    @Resource
    private UserService userService;
    @Resource
    private CdjgCOrderHandle cdjgCOrderHandle;
    @Resource
    private CdjgOrderHandle cdjgOrderHandle;
    @Resource
    private PjOrderHandle pjOrderHandle;
    @Resource
    private XcpOrderHandle xcpOrderHandle;
    @Resource
    private XianOrderHandle xianOrderHandle;

    @Resource
    private LJOrderHandle ljOrderHandle;

    @Resource
    private FsOrderHandle fsOrderHandle;

    @Resource
    private YLOrderHandle ylOrderHandle;
    @Resource
    private LpsOrderLjService lpsOrderLjService;
    @Resource
    private LpsOrderYlService lpsOrderYlService;

    @Resource
    private LpsOrderLjMapper lpsOrderLjMapper;
    @Resource
    private LpsOrderYlMapper lpsOrderYlMapper;

    @Resource
    private LpsOrderFsMapper lpsOrderFsMapper;
    @Resource(name = "clientInboundChannelExecutor")
    private Executor asyncServiceExecutor;

    @Resource
    @Lazy
    private LpsOrderDownloadService lpsOrderDownloadService;

    @Resource
    private MsgSender msgSender;
    /**
     * 60 * 60 * 3 = 10800 = 三小时
     */
    @Value("${lps.delayTime:10800}")
    private Long delayTime;


    /**
     * 获取莱普森订单分页列表
     *
     * @param queryParams 查询参数
     * @return {@link IPage<LpsOrderVO>} 莱普森订单分页列表
     */
    @Override
    public IPage<LpsOrderVO> getLpsOrderPage(LpsOrderQuery queryParams) {
        Page<LpsOrderVO> pageVO = this.baseMapper.getLpsOrderPage(new Page<>(queryParams.getPageNum(), queryParams.getPageSize()), queryParams);
        return pageVO;
    }

    /**
     * 获取莱普森订单表单数据
     *
     * @param orderId 莱普森订单ID
     * @return
     */
    @Override
    public LpsOrderForm getLpsOrderFormData(Long orderId) {
        LpsOrder entity = this.getById(orderId);
        if (entity == null) {
            throw new BusinessException("订单不存在");
        }
        LpsOrderForm orderForm = lpsOrderConverter.toForm(entity);

        List<LpsOrderFsVO> fsList = lpsOrderFsMapper.selectList(new LambdaQueryWrapper<LpsOrderFs>().eq(LpsOrderFs::getOrderId, orderId).orderByDesc(LpsOrderFs::getId)).stream().map(item -> {
            LpsOrderFsVO lpsOrderCdjgVO = new LpsOrderFsVO();
            BeanUtils.copyProperties(item, lpsOrderCdjgVO);
            return lpsOrderCdjgVO;
        }).toList();
        orderForm.setFsList(fsList);

        List<LpsOrderCdjgVO> cdjgList = lpsOrderCdjgMapper.selectList(new LambdaQueryWrapper<LpsOrderCdjg>().eq(LpsOrderCdjg::getOrderId, orderId).orderByDesc(LpsOrderCdjg::getId)).stream().map(item -> {
            LpsOrderCdjgVO lpsOrderCdjgVO = new LpsOrderCdjgVO();
            BeanUtils.copyProperties(item, lpsOrderCdjgVO);
            return lpsOrderCdjgVO;
        }).toList();
        orderForm.setCdjgList(cdjgList);

        List<LpsOrderCdjgCVO> cdjgCList = lpsOrderCdjgCMapper.selectList(new LambdaQueryWrapper<LpsOrderCdjgC>().eq(LpsOrderCdjgC::getOrderId, orderId).orderByDesc(LpsOrderCdjgC::getId)).stream().map(item -> {
            LpsOrderCdjgCVO lpsOrderCdjgCVO = new LpsOrderCdjgCVO();
            BeanUtils.copyProperties(item, lpsOrderCdjgCVO);
            return lpsOrderCdjgCVO;
        }).toList();
        orderForm.setCdjgCList(cdjgCList);

        List<LpsOrderPjVO> pjList = lpsOrderPjMapper.selectList(new LambdaQueryWrapper<LpsOrderPj>().eq(LpsOrderPj::getOrderId, orderId).orderByDesc(LpsOrderPj::getId)).stream().map(item -> {
            LpsOrderPjVO lpsOrderPjVO = new LpsOrderPjVO();
            BeanUtils.copyProperties(item, lpsOrderPjVO);
            return lpsOrderPjVO;
        }).toList();
        orderForm.setPjList(pjList);

        List<LpsOrderXcpVO> xcpList = lpsOrderXcpMapper.selectList(new LambdaQueryWrapper<LpsOrderXcp>().eq(LpsOrderXcp::getOrderId, orderId).orderByAsc(LpsOrderXcp::getId)).stream().map(item -> {
            LpsOrderXcpVO lpsOrderXcpVO = new LpsOrderXcpVO();
            BeanUtils.copyProperties(item, lpsOrderXcpVO);
            return lpsOrderXcpVO;
        }).toList();
        orderForm.setXcpList(xcpList);

        List<LpsOrderXianVO> xianList = lpsOrderXianMapper.selectList(new LambdaQueryWrapper<LpsOrderXian>().eq(LpsOrderXian::getOrderId, orderId).orderByDesc(LpsOrderXian::getId)).stream().map(item -> {
            LpsOrderXianVO lpsOrderXianVO = new LpsOrderXianVO();
            BeanUtils.copyProperties(item, lpsOrderXianVO);
            return lpsOrderXianVO;
        }).toList();
        orderForm.setXianList(xianList);

        List<LpsOrderYlVO> ylList = lpsOrderYlMapper.selectList(new LambdaQueryWrapper<LpsOrderYl>().eq(LpsOrderYl::getOrderId, orderId).orderByDesc(LpsOrderYl::getId)).stream().map(item -> {
            LpsOrderYlVO lpsOrderYlVO = new LpsOrderYlVO();
            BeanUtils.copyProperties(item, lpsOrderYlVO);
            return lpsOrderYlVO;
        }).toList();
        orderForm.setYlList(ylList);

        List<LpsOrderLjVO> ljList = lpsOrderLjMapper.selectList(new LambdaQueryWrapper<LpsOrderLj>().eq(LpsOrderLj::getOrderId, orderId).orderByDesc(LpsOrderLj::getId)).stream().map(item -> {
            LpsOrderLjVO orderLjVO = new LpsOrderLjVO();
            BeanUtils.copyProperties(item, orderLjVO);
            return orderLjVO;
        }).toList();
        orderForm.setLjList(ljList);

        return orderForm;
    }

    /**
     * 新增莱普森订单
     *
     * @param formData 莱普森订单表单对象
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveLpsOrder(LpsOrderForm formData) {
        Long userId = SecurityUtils.getUserId();
        User user = userService.getById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        LpsOrder entity = lpsOrderConverter.toEntity(formData);
        entity.setId(IdUtil.getSnowflakeNextId());
        entity.setUserId(user.getId());
        entity.setDeptId(user.getDeptId());
        entity.setUpdateUserId(userId);
        entity.setCreateBy(userId);
        entity.setUpdateBy(userId);
        entity.setUpdateTime(LocalDateTime.now());
        entity.setCreateTime(LocalDateTime.now());


        List<String> names = new ArrayList<>();
        List<Integer> orderType = new ArrayList<>();
        if (CollUtil.isNotEmpty(formData.getCdjgList())
                || CollUtil.isNotEmpty(formData.getCdjgCList())
                || CollUtil.isNotEmpty(formData.getPjList())
                || CollUtil.isNotEmpty(formData.getXcpList())
                || CollUtil.isNotEmpty(formData.getXianList())
                || CollUtil.isNotEmpty(formData.getFsList())
        ) {

            List<String> orderTypeName = new ArrayList<>();
            if (CollUtil.isNotEmpty(formData.getCdjgList())) {
                orderType.add(LpsOrderTypeEnum.CD_JG.getType());
                orderTypeName.add(LpsOrderTypeEnum.CD_JG.getName());
            }
            if (CollUtil.isNotEmpty(formData.getCdjgCList())) {
                orderType.add(LpsOrderTypeEnum.CD_JG_C.getType());
                orderTypeName.add(LpsOrderTypeEnum.CD_JG_C.getName());
            }
            if (CollUtil.isNotEmpty(formData.getPjList())) {
                orderType.add(LpsOrderTypeEnum.PJ.getType());
                orderTypeName.add(LpsOrderTypeEnum.PJ.getName());
            }
            if (CollUtil.isNotEmpty(formData.getXcpList())) {
                orderType.add(LpsOrderTypeEnum.XCP.getType());
                orderTypeName.add(LpsOrderTypeEnum.XCP.getName());
            }
            if (CollUtil.isNotEmpty(formData.getXianList())) {
                orderType.add(LpsOrderTypeEnum.XCP_XIAN.getType());
                orderTypeName.add(LpsOrderTypeEnum.XCP_XIAN.getName());
            }
            if (CollUtil.isNotEmpty(formData.getFsList())){
                orderType.add(LpsOrderTypeEnum.FS.getType());
                orderTypeName.add(LpsOrderTypeEnum.FS.getName());
            }

            String name = "迅达(" + StrUtil.join(",", orderTypeName) + ")";
            names.add("迅达");
        }
        if (CollUtil.isNotEmpty(formData.getYlList())) {
            names.add(LpsOrderTypeEnum.YL.getName());
            orderType.add(LpsOrderTypeEnum.YL.getType());
        }
        if (CollUtil.isNotEmpty(formData.getLjList())) {
            names.add(LpsOrderTypeEnum.LJ.getName());
            orderType.add(LpsOrderTypeEnum.LJ.getType());
        }
        String fileName = "慈溪莱普森机械有限公司_%s_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String format = CollUtil.join(names, "_");
        entity.setFileName(String.format(fileName, format));
        entity.setOrderType(JSONUtil.toJsonStr(orderType));

        saveLpsOrder(formData, entity, userId);
        boolean save = this.save(entity);
        if (save) {
            //msgSender.sendDelayMessage("saveLpsOrder", entity, 60 * 60 * 3);  //三小时
            msgSender.sendDelayMessage("saveLpsOrder", entity.getId(), delayTime);  //三小时
        }
        return save;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveLpsOrder(LpsOrderForm formData, LpsOrder entity, Long userId) {
        if (CollUtil.isNotEmpty(formData.getFsList())) {
            List<LpsOrderFs> fsList = formData.getFsList().stream().map(item -> {
                LpsOrderFs order = new LpsOrderFs();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).collect(Collectors.toList());
            lpsOrderFsMapper.batchInsert(fsList);
        }
        if (CollUtil.isNotEmpty(formData.getYlList())) {
            List<LpsOrderYl> ylList = formData.getYlList().stream().map(item -> {
                LpsOrderYl order = new LpsOrderYl();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).collect(Collectors.toList());
            lpsOrderYlMapper.batchInsert(ylList);
        }
        if (CollUtil.isNotEmpty(formData.getLjList())) {
            List<LpsOrderLj> ljList = formData.getLjList().stream().map(item -> {
                LpsOrderLj order = new LpsOrderLj();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).collect(Collectors.toList());
            lpsOrderLjMapper.batchInsert(ljList);
        }
        if (CollUtil.isNotEmpty(formData.getCdjgList())) {
            List<LpsOrderCdjg> cdjgList = formData.getCdjgList().stream().map(item -> {
                LpsOrderCdjg order = new LpsOrderCdjg();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).collect(Collectors.toList());
            lpsOrderCdjgMapper.batchInsert(cdjgList);
        }
        if (CollUtil.isNotEmpty(formData.getCdjgCList())) {
            List<LpsOrderCdjgC> cdjgCList = formData.getCdjgCList().stream().map(item -> {
                LpsOrderCdjgC order = new LpsOrderCdjgC();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).toList();
            lpsOrderCdjgCMapper.batchInsert(cdjgCList);
        }

        if (CollUtil.isNotEmpty(formData.getPjList())) {
            List<LpsOrderPj> orderPjList = formData.getPjList().stream().map(item -> {
                LpsOrderPj order = new LpsOrderPj();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).toList();
            lpsOrderPjMapper.batchInsert(orderPjList);
        }

        if (CollUtil.isNotEmpty(formData.getXcpList())) {
            List<LpsOrderXcp> orderXcpList = formData.getXcpList().stream().map(item -> {
                LpsOrderXcp order = new LpsOrderXcp();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                //order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).toList();
            lpsOrderXcpMapper.batchInsert(orderXcpList);
        }

        if (CollUtil.isNotEmpty(formData.getXianList())) {
            List<LpsOrderXian> orderXianList = formData.getXianList().stream().map(item -> {
                LpsOrderXian order = new LpsOrderXian();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).collect(Collectors.toList());
            lpsOrderXianMapper.batchInsert(orderXianList);
        }
    }

    /**
     * 更新莱普森订单
     *
     * @param orderId  莱普森订单ID
     * @param formData 莱普森订单表单对象
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLpsOrder(Long orderId, LpsOrderForm formData) {
        LpsOrder entity = this.getById(orderId);
        if (entity == null) {
            throw new BusinessException("订单不存在");
        }
        Long userId = SecurityUtils.getUserId();
        LpsOrder lpsOrder = lpsOrderConverter.toEntity(formData);
        lpsOrder.setUpdateBy(userId);
        lpsOrder.setUpdateTime(LocalDateTime.now());
        lpsOrder.setUpdateUserId(userId);

        //删除订单记录
        lpsOrderXcpMapper.deleteByOrderIds(CollUtil.newArrayList(orderId));
        if (CollUtil.isNotEmpty(formData.getXcpList())) {
            List<LpsOrderXcp> orderXcpList = formData.getXcpList().stream().map(item -> {
                LpsOrderXcp order = new LpsOrderXcp();
                BeanUtils.copyProperties(item, order);
                order.setOrderId(entity.getId());
                order.setId(IdUtil.getSnowflakeNextId());
                order.setCreateBy(userId);
                order.setUpdateBy(userId);
                return order;
            }).toList();
            lpsOrderXcpMapper.batchInsert(orderXcpList);
        }
        return this.updateById(lpsOrder);
    }

    /**
     * 删除订单详情
     *
     * @param orderIds
     */
    private void delOrderItem(List<Long> orderIds) {
        lpsOrderCdjgMapper.deleteByOrderIds(orderIds);
        lpsOrderCdjgCMapper.deleteByOrderIds(orderIds);
        lpsOrderPjMapper.deleteByOrderIds(orderIds);
        lpsOrderXcpMapper.deleteByOrderIds(orderIds);
        lpsOrderXianMapper.deleteByOrderIds(orderIds);
        lpsOrderYlMapper.deleteByOrderIds(orderIds);
        lpsOrderLjMapper.deleteByOrderIds(orderIds);
        lpsOrderFsMapper.deleteByOrderIds(orderIds);
        lpsOrderDownloadService.deleteByOrderIds(orderIds);
    }

    /**
     * 删除莱普森订单
     *
     * @param ids 莱普森订单ID，多个以英文逗号(,)分割
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteLpsOrders(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的莱普森订单数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();

        delOrderItem(idList);
        return this.removeByIds(idList);
    }

    /**
     * 利居识别号
     */
    public final static Integer LJ_INDEX = 2;
    /**
     * 永乐物料
     */
    public final static Integer YL_INDEX = 1;
    /**
     * 物料
     */
    public final static Integer INDEX = 5;

    public final static String WL = "物料";
    public final static String SBH = "识别号";

    public LpsOrderExcelVO getLpsOrderExcelData(List<MultipartFile> files) throws IOException {
        LpsOrderExcelVO orderExcelVO = new LpsOrderExcelVO();

        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                continue;
            }

            // 检查文件扩展名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null ||
                    (!originalFilename.toLowerCase().endsWith(".xlsx") &&
                            !originalFilename.toLowerCase().endsWith(".xls"))) {
                log.warn("跳过非Excel文件: {}", originalFilename);
                continue;
            }

            try (InputStream inputStream = file.getInputStream()) {
                // 验证是否为有效的Excel文件
                ExcelReader reader = null;
                try {
                    reader = ExcelUtil.getReader(inputStream);
                } catch (Exception e) {
                    throw new BusinessException("[" + originalFilename + "]不是有效的Excel格式,请使用WPS等工具将格式另存为.xlsx/.xls后重试");
                }
                List<List<Object>> sheet1Data = reader.read(0);

                if (sheet1Data.isEmpty()) {
                    continue;
                }

                List<Object> headerRow = sheet1Data.get(0);

                // 判断是否为 OrderExcelVO 类型表格
                if (headerRow.size() > INDEX && WL.equals(headerRow.get(INDEX))) {
                    List<OrderExcelVO> list = EasyExcel.read(file.getInputStream(), OrderExcelVO.class, null).autoCloseStream(false).headRowNumber(1)// 跳过表头
                            .doReadAllSync();
                    orderExcelVO.getOrderExcelList().addAll(list);
                    continue;
                }

                // 判断是否为 YLOrderExcelVO 类型表格
                if (headerRow.size() > YL_INDEX && WL.equals(headerRow.get(YL_INDEX))) {
                    List<YLOrderExcelVO> list = EasyExcel.read(file.getInputStream(), YLOrderExcelVO.class, null).autoCloseStream(false).headRowNumber(1)// 跳过表头
                            .doReadAllSync();
                    orderExcelVO.getYlOrderExcelList().addAll(list);
                    continue;
                }
                headerRow = sheet1Data.get(9);
                // 判断是否为 LJOrderExcelVO 类型表格
                if (headerRow.size() > LJ_INDEX && SBH.equals(headerRow.get(LJ_INDEX))) {
                    List<LJOrderExcelVO> list = EasyExcel.read(file.getInputStream(), LJOrderExcelVO.class, null).autoCloseStream(false).headRowNumber(11).doReadAllSync();
                    list = list.stream().filter(order -> StrUtil.isNotBlank(order.getWl())).collect(Collectors.toList());
                    orderExcelVO.getLjOrderExcelList().addAll(list);

                }
            }
        }
        if (CollUtil.isEmpty(orderExcelVO.getOrderExcelList())
                && CollUtil.isEmpty(orderExcelVO.getLjOrderExcelList())
                && CollUtil.isEmpty(orderExcelVO.getYlOrderExcelList())) {
            throw new BusinessException("导入数据为空，请上传有效的订单文件");
        }
        if (CollUtil.isNotEmpty(orderExcelVO.getOrderExcelList())){
            orderExcelVO.getOrderExcelList().parallelStream().forEach(item -> {
                if (StrUtil.isNotBlank(item.getJhrq())){
                    try {
                        String jhrq = DateUtil.parse(item.getJhrq()).toLocalDateTime().toLocalDate().toString();
                        item.setJhrq(jhrq);
                    }catch (Exception e){
                        log.error("交货日期格式化失败:{}", item.getJhrq());
                    }
                }
            });
        }
        if (CollUtil.isNotEmpty(orderExcelVO.getYlOrderExcelList())){
            orderExcelVO.getYlOrderExcelList().parallelStream().forEach(item -> {
                if (StrUtil.isNotBlank(item.getJhrq())){
                    try {
                        String jhrq = DateUtil.parse(item.getJhrq()).toLocalDateTime().toLocalDate().toString();
                        item.setJhrq(jhrq);
                    }catch (Exception e){
                        log.error("交货日期格式化失败:{}", item.getJhrq());
                    }
                }
            });
        }
        if (CollUtil.isNotEmpty(orderExcelVO.getLjOrderExcelList())){
            orderExcelVO.getLjOrderExcelList().parallelStream().forEach(item -> {
                if (StrUtil.isNotBlank(item.getJhrq())){
                    try {
                        String jhrq = DateUtil.parse(item.getJhrq()).toLocalDateTime().toLocalDate().toString();
                        item.setJhrq(jhrq);
                    }catch (Exception e){
                        log.error("交货日期格式化失败:{}", item.getJhrq());
                    }
                }
            });
        }
        return orderExcelVO;
    }


    @Override
    public LpsOrderImportExcelResultVO importExcel(List<MultipartFile> files) throws Exception {
        LpsOrderExcelVO excelData = getLpsOrderExcelData(files);
        List<CommonOrderVO> list = new ArrayList<>(excelData.getOrderExcelList().stream().map(item -> {
            CommonOrderVO commonOrderVO = new CommonOrderVO();
            BeanUtils.copyProperties(item, commonOrderVO);
            return commonOrderVO;
        }).toList());

        List<LJOrderExcelVO> ljOrderExcelList = excelData.getLjOrderExcelList();
        List<YLOrderExcelVO> ylOrderExcelList = excelData.getYlOrderExcelList();
        //查询物料号对应的分类
        List<LpsWl> lpsWlList = lpsWlService.getByNoList(new ArrayList<>());
        if (lpsWlList.isEmpty()) {
            throw new BusinessException("请先导入的物料数据 无法匹配");
        }
        // 将lpsWlList转为map
        Map<String, LpsWl> lpsWlMap = lpsWlList.stream().collect(Collectors.toMap(LpsWl::getNo, lpsWl -> lpsWl));

        List<CommonOrderVO> orderPjList = new ArrayList<>();
        List<CommonOrderVO> orderXianList = new ArrayList<>();
        List<CommonOrderVO> orderXcpList = new ArrayList<>();
        List<CommonOrderVO> orderCdjgList = new ArrayList<>();
        List<CommonOrderVO> orderCdjgCList = new ArrayList<>();
        List<CommonOrderVO> orderFsList = new ArrayList<>();

        for (CommonOrderVO item : list) {
            LpsWl lpsWl = lpsWlMap.get(item.getWl());
            if (Objects.isNull(lpsWl) || Objects.equals(lpsWl.getParentId(), OrderTypeEnum.OTHER.getType())) {

                if (Objects.equals(lpsWl.getParentId(), OrderTypeEnum.OTHER.getType())){
                    orderFsList.add(item);
                }else {
                    // 没有对应的物料 则归属配件
                    orderPjList.add(item);
                }
                continue;
            }
            OrderTypeEnum typeEnum = OrderTypeEnum.getByType(lpsWl.getParentId());
            switch (Objects.requireNonNull(typeEnum)) {
                case XCP:
                    orderXcpList.add(item);
                    break;
                case XCP_XIAN:
                    orderXianList.add(item);
                    break;
                case CD_JG_C:
                    orderCdjgCList.add(item);
                    break;
                case CD_JG:
                    orderCdjgList.add(item);
                    break;
                case PJ:
                    orderPjList.add(item);
                    break;
                default:
                    log.error("未知的订单类型");
            }
        }

        CompletableFuture<List<LpsOrderPjVO>> future1 = CompletableFuture.supplyAsync(() -> pjOrderHandle.handle(orderPjList, lpsWlMap), asyncServiceExecutor);
        CompletableFuture<List<LpsOrderCdjgVO>> future2 = CompletableFuture.supplyAsync(() -> cdjgOrderHandle.handle(orderCdjgList, lpsWlMap), asyncServiceExecutor);
        CompletableFuture<List<LpsOrderXcpVO>> future3 = CompletableFuture.supplyAsync(() -> xcpOrderHandle.handle(orderXcpList, lpsWlMap), asyncServiceExecutor);
        CompletableFuture<List<LpsOrderXianVO>> future4 = CompletableFuture.supplyAsync(() -> xianOrderHandle.handle(orderXianList, lpsWlMap), asyncServiceExecutor);
        CompletableFuture<List<LpsOrderCdjgCVO>> future5 = CompletableFuture.supplyAsync(() -> cdjgCOrderHandle.handle(orderCdjgCList, lpsWlMap), asyncServiceExecutor);
        CompletableFuture<List<LpsOrderYlVO>> future6 = CompletableFuture.supplyAsync(() -> ylOrderHandle.handle(ylOrderExcelList, lpsWlMap), asyncServiceExecutor);
        CompletableFuture<List<LpsOrderLjVO>> future7 = CompletableFuture.supplyAsync(() -> ljOrderHandle.handle(ljOrderExcelList, lpsWlMap), asyncServiceExecutor);
        CompletableFuture<List<LpsOrderFsVO>> future8 = CompletableFuture.supplyAsync(() -> fsOrderHandle.handle(orderFsList, lpsWlMap), asyncServiceExecutor);


        CompletableFuture.allOf(future1, future2, future3, future4, future5, future6, future7, future8).get();

        LpsOrderImportExcelResultVO resultVO = new LpsOrderImportExcelResultVO();
        resultVO.setPjList(future1.get());
        resultVO.setCdjgList(future2.get());
        resultVO.setXcpList(future3.get());
        resultVO.setXianList(future4.get());
        resultVO.setCdjgCList(future5.get());
        resultVO.setYlList(future6.get());
        resultVO.setLjList(future7.get());
        resultVO.setFsList(future8.get());
        return resultVO;
    }

    /**
     * 下载
     *
     * @param queryParams
     * @param response
     */
    @Override
    public void download(LpsOrderQuery queryParams, HttpServletResponse response) throws Exception {
        Long orderId = Long.valueOf(queryParams.getIds());
        LpsOrder lpsOrder = baseMapper.selectById(orderId);
        if (Objects.isNull(lpsOrder)) {
            throw new BusinessException("下载的订单数据不存在");
        }

        SysUserDetails userDetails = SecurityUtils.getUser().orElse(null);
        if (Objects.isNull(userDetails)) {
            throw new BusinessException("请先登录");
        }

        User user = userService.getById(userDetails.getUserId());
        if (Objects.isNull(user)) {
            throw new BusinessException("请先登录");
        }

        lpsOrderDownloadService.handleLpsOrderDownload(userDetails, lpsOrder);

        String orderType = user.getOrderType();
        List<Integer> userOrderTypeList = new ArrayList<>();
        if (StrUtil.isNotBlank(orderType)) {
            userOrderTypeList = JSONUtil.toList(orderType, Integer.class);
        }

        // 设置响应头
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(lpsOrder.getFileName(), "UTF-8"));

        List<LpsOrderCdjgExcel> lpsOrderCdjgList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.CD_JG.getType())) {
            lpsOrderCdjgList = lpsOrderCdjgMapper.getExcelList(orderId);
        }
        List<LpsOrderCdjgCExcel> lpsOrderCdjgCList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.CD_JG_C.getType())) {
            lpsOrderCdjgCList = lpsOrderCdjgCMapper.getExcelList(orderId);
        }
        List<LpsOrderYlExcel> lpsOrderYlList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.YL.getType())) {
            lpsOrderYlList = lpsOrderYlMapper.getExcelList(orderId);
        }
        List<LpsOrderLjExcel> lpsOrderLjList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.LJ.getType())) {
            lpsOrderLjList = lpsOrderLjMapper.getExcelList(orderId);
        }
        List<LpsOrderXcpExcel> lpsOrderXcpList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.XCP.getType())) {
            lpsOrderXcpList = lpsOrderXcpMapper.getExcelList(orderId);
        }
        List<LpsOrderXianExcel> lpsOrderXianList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.XCP_XIAN.getType())) {
            lpsOrderXianList = lpsOrderXianMapper.getExcelList(orderId);
        }
        List<LpsOrderPjExcel> lpsOrderPjList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.PJ.getType())) {
            lpsOrderPjList = lpsOrderPjMapper.getExcelList(orderId);
        }
        List<LpsOrderFsExcel> lpsOrderFsList = new ArrayList<>();
        if (CollUtil.isEmpty(userOrderTypeList) || userOrderTypeList.contains(LpsOrderTypeEnum.FS.getType())) {
            lpsOrderFsList = lpsOrderFsMapper.getExcelList(orderId);
        }


        try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
            writeExcelToZip(zipOut, lpsOrderCdjgList, ExcelTemplateEnum.CD_JG);
            writeExcelToZip(zipOut, lpsOrderCdjgCList, ExcelTemplateEnum.CD_JG_C);
            writeExcelToZip(zipOut, lpsOrderYlList, ExcelTemplateEnum.YL);
            writeExcelToZip(zipOut, lpsOrderLjList, ExcelTemplateEnum.LJ);
            writeExcelToZip(zipOut, lpsOrderXcpList, ExcelTemplateEnum.XCP);
            writeExcelToZip(zipOut, lpsOrderXianList, ExcelTemplateEnum.XCP_XIAN);
            writeExcelToZip(zipOut, lpsOrderPjList, ExcelTemplateEnum.PJ);
            writeExcelToZip(zipOut, lpsOrderFsList, ExcelTemplateEnum.FS);
        } catch (Exception e) {
            log.error("莱普森订单导出失败:{}", e.getMessage());
            throw new BusinessException("莱普森订单导出失败");
        }
    }

    /**
     * 将数据写入 ZIP 中的 Excel 文件
     *
     * @param zipOut   ZIP 输出流
     * @param dataList 数据列表
     */
    private void writeExcelToZip(ZipOutputStream zipOut, List<?> dataList, ExcelTemplateEnum templateEnum) throws IOException {
        if (dataList == null || dataList.isEmpty()) {
            return;
        }

        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {

            String fileName = String.format(templateEnum.getFileName(), LocalDate.now());
            InputStream resourceAsStream = ExcelUtils.class.getClassLoader().getResourceAsStream(templateEnum.getPath());
            if (templateEnum == ExcelTemplateEnum.XCP_XIAN) {
                ExcelFillMergeHandler mergeHandler = new ExcelFillMergeHandler(Arrays.asList(0, 1, 2, 3, 4, 5, 6), true, 25, 2);
                EasyExcel.write(byteArrayOutputStream).withTemplate(resourceAsStream).registerWriteHandler(mergeHandler).sheet().doFill(dataList);
            } else {
                EasyExcel.write(byteArrayOutputStream).withTemplate(resourceAsStream).sheet().doFill(dataList);
            }

            // 添加 ZIP Entry
            zipOut.putNextEntry(new ZipEntry(fileName));
            zipOut.write(byteArrayOutputStream.toByteArray());
            zipOut.closeEntry();
        }
    }

    @Override
    public List<LpsOrderNODownloadVO> getNoDownloadUserList(Set<String> userNames) {
        return baseMapper.getNoDownloadUserList(userNames);
    }

    @Override
    public LpsOrderNODownloadVO getNoDownloadUser(String userNames) {
        return baseMapper.getNoDownloadUser(userNames);
    }
}
